#include "ssDBPoolThread.h"
#include "log/ssLogger.h"

namespace StarSeeker
{


ssDBPoolThread::ssDBPoolThread()
	:m_mysqlPool(0)
{
}

ssDBPoolThread::ssDBPoolThread(ssMySQLPool* c)
	:m_mysqlPool(c)
{
}

ssDBPoolThread::~ssDBPoolThread()
{
}

void ssDBPoolThread::HandleMessage(ssMsg_s &m)
{
	//解析网络消息
	ssNetMsgHead* head = (ssNetMsgHead*)m.param[1];
	char* data = (char*)m.param[1];
	bool ret = OnDBMsg(head, data + sizeof(ssNetMsgHead), head->m_dwLen - sizeof(ssNetMsgHead), (u32)m.param[0]);

	if (ret)
	{
		//!!需要对象池
		delete[] data;
	} 
	else
	{
		PostMsg(m);
	}
}

void ssDBPoolThread::SetMySQLPool(ssMySQLPool* c)
{
	m_mysqlPool = c;
}

bool ssDBPoolThread::OnDBMsgNullRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		SS_EXP_TRY
			query->QueryByID(id, dataLen, pData);
			if (query->GetResultFlag(id) & DB_RESULT_INSERT_ID)
			{
				u32 row = (u32)query->GetAffectedRows();
				u32 inId = (u32)query->GetInsertID();
				ssDBResParam rp = {};
				//!!需要对象池
				ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
				rp.param = *param;
				rp.row = row;
				rp.insertId = inId;
				u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam);
				pHead->m_dwLen = sendLen;
				char* sendBuf = new char[sendLen + 8];
				memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
				memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
				SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
			}
		SS_EXP_CATCH
			SS_LOG->PrintEx(err.GetErrorMsg());
		SS_EXP_END
		m_mysqlPool->ReleaseConnection(query);
		return true;
	}
	else
	{
		return false;
	}
}

bool ssDBPoolThread::OnDBMsgOneRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		SS_EXP_TRY
			query->QueryByID(id, dataLen, pData);
			ssWriteBytes& wb = query->GetOneResult(id);
			u32 row = query->GetRows();
			ssDBResParam rp = {};

			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + wb.Size();
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];

			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
			if (row>0)
			{
				memcpy(sendBuf + sizeof(ssNetMsgHead) + sizeof(ssDBResParam), wb.Buf(), wb.Size());
			}
			SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
		SS_EXP_CATCH
			SS_LOG->PrintEx(err.GetErrorMsg());
		SS_EXP_END
		m_mysqlPool->ReleaseConnection(query);
		return true;
	} 
	else
	{
		return false;
	}
}

bool ssDBPoolThread::OnDBMsgMultiRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		SS_EXP_TRY
			query->QueryByID(id, dataLen, pData);
			ssMultiLineBuffer& ob = query->GetResultSet(id);
			u32 row = query->GetRows();
			ssDBResParam rp = {};

			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + ob.Size();
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];
			char* sendFirst = sendBuf;

			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			sendBuf += sizeof(ssNetMsgHead);
			memcpy(sendBuf, &rp, sizeof(ssDBResParam));
			if (row > 0)
			{
				sendBuf += sizeof(ssDBResParam);
				memcpy(sendBuf, ob.Buf(), ob.Size());
			}
			SendResponse(connectID, (ssNetMsgHead*)sendFirst, sendFirst, sendLen);
		SS_EXP_CATCH
			SS_LOG->PrintEx(err.GetErrorMsg());
		SS_EXP_END
		m_mysqlPool->ReleaseConnection(query);
		return true;
	}
	else
	{
		return false;
	}
}

void ssDBPoolThread::OnDBMsgCleanBuffer()
{
	m_mysqlPool->ClearAllBuffer();
}

}
